package com.zhm.demo.controller;

import com.zhm.demo.bean.ChartBean;
import com.zhm.demo.bean.PointBean;
import com.zhm.demo.mysql.entity.Devices;
import com.zhm.demo.mysql.pre.mapper.PreDevicesMapper;
import com.zhm.demo.security.LoginUser;
import jakarta.annotation.Resource;
import jakarta.annotation.security.PermitAll;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.*;


import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController()
@RequestMapping("/demo")
public class TestController {

    @Autowired
    private PreDevicesMapper preDevicesMapper;

    @GetMapping("listAllLatLng")
    public List<Devices> listAllLatLng() {
        return preDevicesMapper.listAllLatLng();
    }

    @GetMapping("rs")
    public ResponseEntity<List<Devices>> rs() {
        return new ResponseEntity<List<Devices>>(preDevicesMapper.listAllLatLng(), HttpStatusCode.valueOf(200));
    }

    @Resource
    private AuthenticationManager authenticationManager;


    @PostMapping("login")
    public String login(@RequestBody LoginUser req) {
        String username = req.getUsername();
        String password = req.getPassword();
        // 用户验证
        Authentication authentication = null;

        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
        // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
        authentication = authenticationManager.authenticate(authenticationToken);
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        return loginUser.getUsername();
    }

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @PostMapping("register")
    public String register(@RequestBody LoginUser req) {
        String encode = passwordEncoder.encode(req.getPassword());
        return encode;
    }


    @PostMapping("postStr")
    public String postStr(@RequestBody String str) {
        log.info(str);
        return str;
    }


    @Deprecated
    @PostMapping("testPost")
    public String testPost(@RequestBody String str) {
        log.info(str);
        return str;
    }

    @GetMapping("testGet")
    public String testGet(@RequestParam(required = false) String str) {
        log.info(str);
        return str;
    }

    /*
    permitAll	允许所有请求，无需认证。
    denyAll	拒绝所有请求。
    isAnonymous()	允许匿名用户访问。
    isAuthenticated()	仅允许已认证用户访问。
    isFullyAuthenticated()	仅允许非记住我（remember-me）方式认证的用户访问。
    hasRole('ROLE_ADMIN')	仅允许拥有 ROLE_ADMIN 角色的用户访问（自动添加 ROLE_ 前缀）。
    hasAuthority('read')	仅允许拥有 read 权限的用户访问。
    hasIpAddress('192.168.1.0/24')	仅允许来自指定 IP 范围的请求。
    hasAnyRole('ADMIN', 'USER')	允许拥有任一指定角色的用户访问。
    hasAnyAuthority('read', 'write')	允许拥有任一指定权限的用户访问。
    @beanName.method(authentication, request)	调用自定义 Bean 方法进行授权决策。
     */

    @PreAuthorize("hasAuthority('read')")
    @GetMapping("hasAuthority")
    public String hasAuthority(@RequestParam(required = false) String str) {
        SecurityContext context = SecurityContextHolder.getContext();
        Authentication authentication = context.getAuthentication();
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        log.info("{}", authorities);
        return str;
    }

    @PermitAll
    @GetMapping("permitAll")
    public String permitAll(@RequestParam(required = false) String str) {
        log.info(str);
        return str;
    }


    @PreAuthorize("isAuthenticated()")
    @GetMapping("isAuthenticated")
    public String isAuthenticated(@RequestParam(required = false) String str) {
        log.info(str);
        return str;
    }

    // 仅允许ADMIN角色访问
    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/root/dashboard")
    public String adminDashboard() {
        return "管理员控制台";
    }


    @GetMapping("listJson")
    public List<ChartBean> listJson(@RequestHeader Map<String, Object> headers) {
        log.info("headers:{}", headers);
        List<ChartBean> chartBeans = new ArrayList<ChartBean>();
        chartBeans.add(new ChartBean(0D, "apple1"));
        chartBeans.add(new ChartBean(1D, "xiaomi1"));
        chartBeans.add(new ChartBean(2D, "huawei1"));
        return chartBeans;
    }

    @GetMapping("listJson1")
    public List<ChartBean> listJson1(@RequestHeader Map<String, Object> headers) {
        log.info("headers:{}", headers);
        List<ChartBean> chartBeans = new ArrayList<ChartBean>();
        chartBeans.add(new ChartBean(11D, "apple1"));
        chartBeans.add(new ChartBean(12D, "xiaomi1"));
        chartBeans.add(new ChartBean(13D, "huawei1"));
        return chartBeans;
    }


    @GetMapping("listJson2")
    public List<ChartBean> listJson2(@RequestHeader Map<String, Object> headers) {
        log.info("headers:{}", headers);
        List<ChartBean> chartBeans = new ArrayList<ChartBean>();
        chartBeans.add(new ChartBean(21D, "apple2"));
        chartBeans.add(new ChartBean(22D, "xiaomi2"));
        chartBeans.add(new ChartBean(23D, "huawei2"));
        return chartBeans;
    }


    @PostMapping("listJson")
    public List<ChartBean> listJson(@RequestBody String str, @RequestHeader Map<String, Object> headers) {
        log.info("headers:{}", headers);
        log.info("body:{}", str);
        List<ChartBean> chartBeans = new ArrayList<>();
        chartBeans.add(new ChartBean(45D, "apple"));
        chartBeans.add(new ChartBean(60D, "xiaomi"));
        chartBeans.add(new ChartBean(35D, "huawei"));
        return chartBeans;
    }

    @PostMapping("listPoint")
    public List<PointBean> listPoint(@RequestBody String str, @RequestHeader Map<String, Object> headers) {
        log.info("headers:{}", headers);
        log.info("body:{}", str);
        List<PointBean> chartBeans = new ArrayList<>();
        chartBeans.add(new PointBean("apple", 22.5445741, 114.0545429));
        chartBeans.add(new PointBean("xiaomi", 22.5645741, 114.0555429));
        chartBeans.add(new PointBean("huawei", 22.6445741, 114.1545429));
        return chartBeans;
    }

    public static void main(String[] args) {
        var c = new Object();
        var o = new Object() {
            public String a = "12";

            {
                int b = 12;
                a = "325";
                System.out.println("123");
            }
        };
        System.out.println(o.a);
    }


}
